/*
 * KKAdapterLayer.cpp
 *
 *  Created on: 2013-9-15
 *      Author: wanghua
 */

#include "KKAdapterLayer.h"
#include "XmlUtils.h"
#include "KKLayout.h"

KKDefaultAdapter::KKDefaultAdapter() {
	m_itemCount = 0;
	m_items = NULL;
}

KKDefaultAdapter::~KKDefaultAdapter() {
	CC_SAFE_DELETE(m_items);
	m_itemCount = 0;
}

void KKDefaultAdapter::addItem(KKNode* item) {

	if (!m_items) {
		m_items = new KKNodeArray();
	}

	m_items->addObject(item);

	m_itemCount = (int) m_items->count();
}

void KKDefaultAdapter::removeItem(KKNode* item) {
	if (!m_items) {
		return;
	}

	m_items->removeObject(item, true);

	m_itemCount = (int) m_items->count();
}

int KKDefaultAdapter::getItemIndex(KKNode* item) {
	return int(m_items->getIndexOfObject(item));
}
KKNode* KKDefaultAdapter::getView(int position, KKNode* parent) {

	int count = int(m_items->count());

	KKNode* item = m_items->getObjectAtIndex(position % count);

	item->setKKParent(parent);

	if (item->getUsed()) {
		item = item->cloneNode(false);
	}

	return item;
}

KKAdapterLayer::KKAdapterLayer() {
	m_selectedNode = NULL;
	m_adapter = NULL;
	m_selection = -1;
	m_firstPosition = -1;
	m_lastPosition = -1;
}

KKAdapterLayer::~KKAdapterLayer() {
	m_selectedNode = NULL;
	CC_SAFE_RELEASE_NULL(m_adapter);
	m_selection = -1;
	m_firstPosition = -1;
	m_lastPosition = -1;

}

void KKAdapterLayer::setAdapter(KKNodeAdapter* adapter) {

	if (m_adapter != adapter) {

		m_adapter = adapter;

		this->removeAllNodes(true);

		layout();
	}
}

bool KKAdapterLayer::initDelayInfoWithXml(TiXmlElement* element) {

	if (KKLayer::initDelayInfoWithXml(element)) {

		KKDefaultAdapter* adapter = NULL;

		if (!this->m_adapter) {
			adapter = new KKDefaultAdapter();
			this->m_adapter = adapter;
		} else {
			adapter = dynamic_cast<KKDefaultAdapter*>(m_adapter);
		}

		if (adapter) {

			adapter->setItems(this->getObjects()->copy());

			adapter->setCount(
					XmlUtils::getIntAttr(element, "itemCount",
							int(this->getObjects()->count())));
		}

		m_selection = XmlUtils::getIntAttr(element, "selection", -1);

		return true;
	}

	return false;
}

void KKAdapterLayer::setSelection(int selection) {

	m_selection = selection;

	KKNodeArray::CCMutableArrayIterator it = m_objects->begin();

	KKNode* child = NULL;

	int childIndex = 0;

	while (it != m_objects->end()) {

		child = *it;

		if (childIndex == selection) {
			this->m_selectedNode = child;
			child->setSelected(true);
		} else {
			child->setSelected(false);
		}
		childIndex++;
		it++;
	}

}

int KKAdapterLayer::getSelection() {

	return m_selection;

}

KKNodeRecycler::KKNodeRecycler() {

}

KKNodeRecycler::~KKNodeRecycler() {
}

bool KKNodeRecycler::addToCache(KKNode* node, const int& pos) {
	KKNodeInfo* nodeInfo = new KKNodeInfo(node);

	nodeInfo->autorelease();

	//	nodeInfo->retain();

	return m_cache.setObject(nodeInfo, pos);
}

bool KKNodeRecycler::removeFromCache(const int& pos) {
	m_cache.removeObjectForKey(pos);

	return true;
}

void KKNodeRecycler::useNode(KKNode* node) {
	node->setUsed(true);
}

KKNode* KKNodeRecycler::getFromCache(const int& pos) {

	KKNodeInfo* nodeInfo = m_cache.objectForKey(pos);

	if (nodeInfo) {

		return nodeInfo->m_node;
	}

	return NULL;

}

void KKNodeRecycler::clear() {

	vector<int> keys = m_cache.allKeys();

	int keyCount = int(keys.size());

	KKNodeInfo* nodeInfo = NULL;

	int key = 0;

	for (int i = 0; i < keyCount; i++) {
		key = keys[i];
		nodeInfo = m_cache.objectForKey(key);

		if (nodeInfo) {
			if (!nodeInfo->isUsed()) {
				nodeInfo->recycleNode();
				m_cache.removeObjectForKey(key);
			} else {
				nodeInfo->recycleNode();
			}

		}
	}

}

void KKNodeRecycler::description() {
	vector<int> keys = m_cache.allKeys();

	int keyCount = int(keys.size());

	KKNodeInfo* nodeInfo = NULL;

	int key = 0;

	for (int i = 0; i < keyCount; i++) {
		key = keys[i];
		nodeInfo = m_cache.objectForKey(key);

		if (nodeInfo) {
			CCLog("key=%d,value=%d,image=%s\n", key, nodeInfo->m_node,
					nodeInfo->m_node->getImage().c_str());
		}
	}
}

KKNodeInfo::KKNodeInfo(KKNode* node) {
	m_node = node;
	if (m_node) {
		m_node->convertToCCNode()->retain();
	}
}

KKNodeInfo::~KKNodeInfo() {
	if (m_node) {
		m_node->convertToCCNode()->release();
	}
}

bool KKNodeInfo::isUsed() {
	return m_node->getUsed();
}
void KKNodeInfo::useNode() {
	m_node->setUsed(true);
}
void KKNodeInfo::recycleNode() {
	m_node->setUsed(false);

}
